﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Windows.Forms;
using wontec_claw;
using PIDHelper;
using System.Text;
using System.Threading;

namespace bootloader
{
    static class Program
    {
        public static UInt16 cal_crc(string str, int length = -1)
        {
            UInt16 itemp = 0xFFFF;
            byte i;
            int index = 0;
            if (null == str) return 0;
            if (length == -1) length = str.Length;
            while (length-- != 0)
            {
                itemp ^= str[index++];
                for (i = 0; i < 8; i++)
                {
                    if ((itemp & 0x1) != 0)
                    {
                        itemp >>= 1;
                        itemp ^= 0xA001;
                    }
                    else
                    {
                        itemp >>= 1;
                    }
                }
            }
            //itemp = (UInt16)(((itemp << 8) | (itemp >> 8)) & 0xffff);
            return itemp;
        }
        static bool Check(string str)
        {
            if (str == null) return false;
            if (str.Length == 0) return false;
            int end = str.IndexOf("\r\n");
            if (end == -1) end = str.Length;
            if (end < 8) return false;
            return str.IndexOf(string.Format("{0:X4}", cal_crc(str, end - 4))) == (end - 4);
        }
        static byte[] AppendCRCHex(string str)
        {
            if (!Check(str))
            {
                var crcb = new byte[2];
                int crc = cal_crc(str);
                crcb[0] = (byte)(crc & 0xff);
                crcb[1] = (byte)((crc >> 8) & 0xff);
                return crcb;
            }
            return null;
        }
        
        /// <summary>
        /// 应用程序的主入口点。
        /// </summary>
        [STAThread]
        static void Main()
        {
            Application.EnableVisualStyles();
            Application.SetCompatibleTextRenderingDefault(false);
            
            
            var groupBox2 = new GroupBox();
            groupBox2.Location = new System.Drawing.Point(12, 170);
            groupBox2.Name = "groupBox2";
            groupBox2.Size = new System.Drawing.Size(434, 88);
            groupBox2.TabIndex = 1;
            groupBox2.TabStop = false;
            groupBox2.Text = "端口";

            var befortextBox1 = new ComboBox();

            befortextBox1.Location = new System.Drawing.Point(243, 39);
            befortextBox1.Name = "befortextBox1";
            befortextBox1.Size = new System.Drawing.Size(200, 21);
            befortextBox1.TabIndex = 9;
            List<int> idlist = new List<int>();
            int selectid=0;

            COMHelper helper = new COMHelper(groupBox2);

            var timeout = 0;

            var ymodem = new YmodemGUI(helper.SendUartData, helper.rxbuffer);

            var devhelper = new sersonhelper();

            var Pipe = new pipeline(helper.rxbuffer, (a) => {
                var data = devhelper[a];
            }, helper.SendUartDataNoLog);

            helper.OnCloseCOM = () => {
                Pipe.Enable = true;
                Pipe.SendData(devhelper['$',0] as string,"");
                idlist.Clear();
                selectid = 0;
                
                ymodem.Invoke(new MethodInvoker(() => {
                    ymodem.panel1.Enabled = true;
                    befortextBox1.Items.Clear();
                }));
                timeout = 5;
            };

            helper.On1SCheck = () => {

                if (timeout != 0)
                {
                    if (--timeout == 0)
                    {

                        Pipe.Enable = false;
                    }
                    if (timeout == 3)
                    {
                        foreach(var i in idlist)
                        {
                            string s = devhelper['A', i] as string;
                            Pipe.SendData(s,s.Substring(0,4));
                        }
                    }
                }
            };

            helper.OnOpenCOM = () => {
                ymodem.Invoke(new MethodInvoker(() => {
                    ymodem.panel1.Enabled = false;
                }));

            };

            var fwurl = new Dictionary<string, string>();
            var fwconnbps=new Dictionary<string, int>();
            fwurl.Add("Cstep v", "https://gitee.com/Cccxs/cstep-open/raw/master/FW/"); fwconnbps.Add("Cstep v", 115200);
            fwurl.Add("Cstep [A]", "https://gitee.com/Cccxs/cstep-open/raw/master/FW/"); fwconnbps.Add("Cstep [A]", 115200);
            fwurl.Add("Cstep [B]", "https://gitee.com/Cccxs/cstep-open/raw/master/[B]FW/"); fwconnbps.Add("Cstep [B]", 115200);
            fwurl.Add("CLS v", "https://gitee.com/ttlrobot/clsensor-open/raw/master/FW/"); fwconnbps.Add("CLS v", 9600);

            devhelper.AddCmd('$', ">%2x%c%2x", ">%2x%c", (key, id, data) => {
                selectid = data[0];
                idlist.Add(selectid);
                ymodem.Invoke(new MethodInvoker(() => {
                    befortextBox1.Items.Add(string.Format("[{0}] 号设备",selectid));
                    befortextBox1.SelectedIndex = befortextBox1.SelectedIndex == -1 ? 0 : befortextBox1.SelectedIndex;
                }));
            });
            devhelper.AddCmd('A', ">%2x%c%s", ">%2x%c", (key, id, data) => {
                if(timeout<3)
                timeout=2;
                    ymodem.Invoke(new MethodInvoker(() => {
                    
                    befortextBox1.Items[idlist.IndexOf(id)] = string.Format("[{0}] 号设备 {1}", id,devhelper.lastString);
                    var var = befortextBox1.SelectedItem.ToString();
                    ymodem.urldata = "";
                    foreach (var k in fwurl.Keys)
                    {
                        if (var.Contains(k))
                        {
                            ymodem.urldata = fwurl[k];
                            ymodem.connectbpscomboBox1.Text = ""+fwconnbps[k];
                        }
                    }
                }));
            });

            befortextBox1.SelectedIndexChanged += (s, e) => {
                ymodem.beforCMD = string.Format("[iap=1,{0},{{0}}]\r\n", idlist[befortextBox1.SelectedIndex]);
                var var = befortextBox1.SelectedItem.ToString();
                ymodem.urldata = "";
                foreach (var k in fwurl.Keys)
                {
                    if (var.Contains(k))
                    {
                        ymodem.urldata = fwurl[k];
                        ymodem.connectbpscomboBox1.Text = "" + fwconnbps[k];
                    }
                }
            };

            ymodem.defbps = helper.COM.BaudRate;
            ymodem.rate = 6300;

            ymodem.uartcmdsender = (b) => {
                var str = Encoding.Default.GetString(b).Replace("\r\n", "");
                var crc = AppendCRCHex(str);
                var crcdata = new byte[] { crc[0], crc[1], (byte)'\r', (byte)'\n' };
                helper.SendUartData(Encoding.Default.GetBytes(str));
                helper.SendUartData(crcdata);
            };
            ymodem.setbps = (int bps) =>
            {
                if (helper.COM.BaudRate == bps) return;
                if (helper.COM.IsOpen)
                {
                    helper.COM.Close();
                    helper.COM.BaudRate = bps;
                    helper.COM.Open();
                }
            };
            ymodem.Height += 108;
            ymodem.Controls.Add(groupBox2);
            ymodem.panel1.Controls.Add(befortextBox1);
            ymodem.panel1.Enabled = false;
            ymodem.FormClosed += (s, e) => {
                Environment.Exit(0);
            };
            Application.Run(ymodem);
        }
    }
}
